﻿#ifndef XQHTTPSERVER_H
#define XQHTTPSERVER_H
#include<QHostAddress>
#include<QReadWriteLock>
#include"XQHttpObject.h"
#define XQHttpServerLog XQLog("XQHttpServer") //http服务器日志
class QTimer;
class XQHttpServer:public XQHttpObject
{
	Q_OBJECT
public:
	XQHttpServer(QObject*parent=nullptr);
	~XQHttpServer();
	//超时连接时间(客户端)
	int timeoutConnection()const;
	QString ip()const;
	quint16 port()const;
	QTcpServer* tcp()const;
	QString serverName_local()const;
	QLocalServer* localServer()const;
	XQTaskPool* taskPool()const;
	QList<QIODevice*> clients();
public:
	//运行
	bool run(NetworkType type);
	void setPort(uint16_t port);
	void setServerName_local(const QString& name);
	//设置超时连接时间(客户端)
	void setTimeoutConnection(int msec);
	//设置线程池运行
	void setThreadPool_run(bool run);
	//设置回复函数
	void setReplyFunc(std::function<XQHttpHeadReply(QIODevice* socket, XQHttpHeadRequest* header, const QByteArray& data)>func);
	//发送信号(向客户端发送响应头)
	void sendSignals(const QString& name, const QVariantList& list);
signals://信号
	//连接上客户端
	void connected(QIODevice* socket);
	//断开与客户端连接
	void disconnected(QIODevice* socket);
protected:
	void init();
	//检查连接超时(客户端)
	void checkTimeoutConnection();
	//运行定时器
	void runTimeoutConnectionTimer();
protected:
	//有新的客户端链接到来
	void readyConnection();
	//断开与客户端连接
	void readyDisconnect(QIODevice* socket);
	//可以读取内容
	void readyRead(QIODevice* socket);
	//处理请求
	void handlingRequests(QIODevice* socket,XQHttpHeadRequest* header, const QByteArray& data);
	//向客户端发送数据
	void send(QIODevice* socket,const QByteArray& data);
protected:
	static XQLog* m_log;//日志服务
	QLocalServer* m_localServer = nullptr;
	QString m_localServerName="localServer";//本地方式时的名字
	QTcpServer* m_tcpServer = nullptr;
	quint16 m_port = 6666;//服务器端口
	QHostAddress m_address= QHostAddress::Any;//服务器host
	QReadWriteLock m_lock;
	QHash<QIODevice*,QByteArray*> m_clientBuffer;//客户端套接字
	QHash<QIODevice*, QDateTime> m_clientTime;//客户端时间
	int m_timeout =0;//超时时间
	QTimer* m_timeoutTimer = nullptr;//检测超时的定时器
	std::function<XQHttpHeadReply(QIODevice* socket, XQHttpHeadRequest* header, const QByteArray& data)>m_readyFunc=nullptr;
	bool m_thread_run = false;//是否线程池运行
	XQTaskPool* m_task=nullptr;//线程池
};
#endif // !XQHttpServer_H
